#==============================================================================
# Theta Scripting Engine - Percentage Protection by privateer
#==============================================================================
# ► Version  : 1.0
#==============================================================================
# ► Introduction
# This script enables you to create states that reduce damages done to its 
# bearer by a percentage amount.
#==============================================================================
# ► Instruction
# Just put this script anywhere below Scene_Debug but above Main.
#==============================================================================
# ► Compatibility
# Designed and tested for DBS. May or not work with exotic CBS and/or scripts
# that alter how damages are done to an unit.
#==============================================================================
# ► Additional Informations
# * When there are multiple percentage protection states, they will be stacked.
# If the resulting protect rate is >= 100, then no damage will be done.
#==============================================================================

module TSE
  module PercentageProtection
    PERCENTAGE_PROTECTION_STATES = {
    # State ID => [protect_rate, physical_or_magical?],
    # protect_rate : Percentage of damages that state will reduce. For example,
    # 50 means damages will be reduced by 50%.
    # physical_or_magical? : Determines what types of actions will activate the
    # state's damage reduction. Either use 'p' for physical actions (attacks and
    # skills with INT_F = 0), 'm' for magical actions (skills with INT_F > 0), 
    # or 'b' for both types of actions.
    # 
    19 => [25, 'p'],
    18 => [30, 'p'],
    20 => [15, 'm'],
    21 => [50, 'b'],
    22 => [10, 'b'],
    }
    
    # Animation ID that will be played when an unit is protected from damages.
    # If you don't want any animation, just set it to 0.
    PROTECTION_ANIMATION_ID = 64
    
    # If true,  healing actions will also be affected by its target's 
    # protect rate.
    AFFECT_HEALINGS = false
    
    # If a weapon or skill has this element ID, it won't be affected
    # by its target's protect rate.
    PERCENTAGE_PROTECTION_UNAFFECTED_ELEMENT_ID = 17
  end
end

#==============================================================================
# DON'T EDIT ANY FURTHER UNLESS YOU KNOW WHAT YOU'RE DOING!
#==============================================================================

$imported = {} if $imported.nil?
$imported["TSE-PercentageProtection"] = true

module RPG
  class State
    include TSE
    include PercentageProtection
    def percentage_protection_datas
    PERCENTAGE_PROTECTION_STATES.has_key?(id) ? PERCENTAGE_PROTECTION_STATES[id] : []
    end
  end
  class Weapon
    include TSE
    include PercentageProtection   
    def pp_unaffected?
      self.element_set.include?(PERCENTAGE_PROTECTION_UNAFFECTED_ELEMENT_ID)
    end
  end
  class Skill
    include TSE
    include PercentageProtection  
    def pp_unaffected?
      self.element_set.include?(PERCENTAGE_PROTECTION_UNAFFECTED_ELEMENT_ID)
    end    
  end
end

class Game_Battler
  include TSE
  include PercentageProtection
  alias tse_percentage_protection_attack_effect attack_effect
  def attack_effect(attacker)
    old_hp = self.hp
    tse_percentage_protection_attack_effect(attacker)
    return if attacker.is_a?(Game_Actor) and $data_weapons[attacker.weapon_id].pp_unaffected?
    return unless self.damage.is_a?(Numeric)
    return if self.damage < 0 and not AFFECT_HEALINGS
    physical_pp_states = @states.find_all{|id|$data_states[id].percentage_protection_datas.include?('p')}
    both_pp_states = @states.find_all{|id|$data_states[id].percentage_protection_datas.include?('b')}
    unless physical_pp_states.empty? and both_pp_states.empty?
      self.hp = old_hp
      protect_rate = 0
      for id in physical_pp_states
        protect_rate += $data_states[id].percentage_protection_datas[0] 
      end
      self.animation_id = PROTECTION_ANIMATION_ID
      self.damage = self.damage - (self.damage * protect_rate / 100)
      self.damage = 0 if self.damage <= 0
      self.hp -= self.damage
    end
  end
  alias tse_percentage_protection_skill_effect skill_effect
  def skill_effect(user, skill)
    old_hp = self.hp
    tse_percentage_protection_skill_effect(user, skill)
    return if skill.pp_unaffected?
    return unless self.damage.is_a?(Numeric)
    return if self.damage < 0 and not AFFECT_HEALINGS
    physical_pp_states = @states.find_all{|id|$data_states[id].percentage_protection_datas.include?('p')}
    both_pp_states = @states.find_all{|id|$data_states[id].percentage_protection_datas.include?('b')}
    magical_pp_states = @states.find_all{|id|$data_states[id].percentage_protection_datas.include?('m')}
    if skill.int_f == 0 # Skill is physical
      unless physical_pp_states.empty and both_pp_states.empty?
        self.hp = old_hp
        protect_rate = 0
        for id in physical_pp_states and both_pp_states
          protect_rate += $data_states[id].percentage_protection_datas[0] 
        end
        self.animation_id = PROTECTION_ANIMATION_ID
        self.damage = self.damage - (self.damage * protect_rate / 100)
        self.damage = 0 if self.damage <= 0
        self.hp -= self.damage
      end
    else # Skill is magical
      unless magical_pp_states.empty and both_pp_states.empty?
        self.hp = old_hp
        protect_rate = 0
        for id in magical_pp_states and both_pp_states
          protect_rate += $data_states[id].percentage_protection_datas[0] 
        end
        self.animation_id = PROTECTION_ANIMATION_ID
        self.damage = self.damage - (self.damage * protect_rate / 100)
        self.damage = 0 if self.damage <= 0
        self.hp -= self.damage        
      end      
    end
  end  
end
